<?php

namespace Frieza\Modules\AdServing\Controllers;

use Encore\Admin\Grid;
use Doraemon\tools\Log;
use Encore\Admin\Grid\Tools;
use Illuminate\Http\Request;
use Encore\Admin\Widgets\Tab;
use Encore\Admin\Widgets\Form;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Layout\Content;
use Illuminate\Support\MessageBag;
use App\Admin\Models\Administrator;
use App\Http\Controllers\Controller;
use Doraemon\model\AdServing\Channel;
use Doraemon\model\AdServing\Serving;
use Doraemon\model\ShortLink\ShortLink;
use Doraemon\model\AdServing\AgentPerson;
use Doraemon\model\AdServing\AgentCompany;
use Doraemon\model\AdServing\UploadApkLog;
use App\Admin\Extensions\Tools\ReleasePost;
use Doraemon\service\AdServing\ChannelService;
use Doraemon\service\AdServing\ServingService;
use App\Pockets\GridDataModel as pGridDataModel;
use Doraemon\service\AdServing\AgentPersonService;
use Doraemon\service\AdServing\AgentCompanyService;
use Frieza\Modules\AdServing\Actions\BatchUpdateAdmin;

class AdServingController extends Controller
{
    const SHORT_PREFIX = 'http://l.hhz1.cn/';

    const PAGE_SIZE = 50;

    public function getList(Request $request, Content $content): Content
    {
        $params = $request->all();
        $params['page'] = $request->input('page', 1);
        $params['per_page'] = $request->input('per_page', self::PAGE_SIZE);

        $condition = [];
        if (isset($params['code']) && !empty($params['code'])) {
            $condition['code'] = $params['code'];
        }
        if (isset($params['channel_one_id']) && !empty($params['channel_one_id'])) {
            $condition['channel_one_id'] = $params['channel_one_id'];
        }
        if (isset($params['channel_two_id']) && !empty($params['channel_two_id'])) {
            $condition['channel_two_id'] = $params['channel_two_id'];
        }
        if (isset($params['status']) && strlen($params['status']) == 1) {
            $condition['status'] = $params['status'];
        }
        if (isset($params['terminal']) && strlen($params['terminal']) == 1) {
            $condition['terminal'] = $params['terminal'];
        }
        if (isset($params['admin_uid']) && (int)$params['admin_uid'] > 0) {
            $condition['admin_uid'] = $params['admin_uid'];
        }
        if (isset($params['agent_company_id']) && (int)$params['agent_company_id'] > 0) {
            $condition['agent_company_id'] = $params['agent_company_id'];
        }
        if (isset($params['agent_person_id']) && (int)$params['agent_person_id'] > 0) {
            $condition['agent_person_id'] = $params['agent_person_id'];
        }
        Log::debug('投放渠道管理过滤', $condition);
        $where = [];
        if (!empty($condition)) {
            $where['AND'] = $condition;
        }

        $data = Serving::select("*", array_merge($where, [
            "LIMIT" => [($params['page'] - 1) * $params['per_page'], $params['per_page']],
            "ORDER" => ['id' => "DESC"]
        ]));
        $total = Serving::count($where);


        $channelOneIdArr = [];
        $channelTwoIdArr = [];
        $channelThreeIdArr = [];
        $companyidArr = [];
        $personidArr = [];
        $adminUidArr = [];
        foreach ($data as $row) {
            $channelOneIdArr[] = $row['channel_one_id'];
            $channelTwoIdArr[] = $row['channel_two_id'];
            $channelThreeIdArr[] = $row['channel_three_id'];
            $companyidArr[] = $row['agent_company_id'];
            $personidArr[] = $row['agent_person_id'];
            if (!in_array($row['admin_uid'], $adminUidArr)) {
                $adminUidArr[] = $row['admin_uid'];
            }
        }

        $channelOneArr = (array)Channel::select('*', [
            'OR' => [
                'id' => $channelOneIdArr,
            ],
        ]);
        $channelOneArrById = [];
        foreach ($channelOneArr as $channelOne) {
            $channelOneArrById[$channelOne['id']] = $channelOne;
        }
        $channelTwoArr = (array)Channel::select('*', [
            'OR' => [
                'id' => $channelTwoIdArr,
            ],
        ]);
        $channelTwoArrById = [];
        foreach ($channelTwoArr as $channelTwo) {
            $channelTwoArrById[$channelTwo['id']] = $channelTwo;
        }
        $channelThreeArr = (array)Channel::select('*', [
            'OR' => [
                'id' => $channelThreeIdArr,
            ],
        ]);
        $channelThreeArrById = [];
        foreach ($channelThreeArr as $channelThree) {
            $channelThreeArrById[$channelThree['id']] = $channelThree;
        }
        $companyArr = (array)AgentCompany::select('*', [
            'OR' => [
                'id' => $companyidArr,
            ],
        ]);
        $companyArrById = [];
        foreach ($companyArr as $company) {
            $companyArrById[$company['id']] = $company;
        }
        $personArr = (array)AgentPerson::select('*', [
            'OR' => [
                'id' => $personidArr,
            ],
        ]);
        $personArrById = [];
        foreach ($personArr as $person) {
            $personArrById[$person['id']] = $person;
        }

        $adminArr = Administrator::whereIn('id', $adminUidArr)->get()->toArray();
        $adminArrById = [];
        foreach ($adminArr as $admin) {
            $adminArrById[$admin['id']] = $admin;
        }

        foreach ($data as $key => $row) {
            $data[$key]['channelOne'] = $channelOneArrById[$row['channel_one_id']];
            $data[$key]['channelTwo'] = $channelTwoArrById[$row['channel_two_id']];
            $data[$key]['channelThree'] = $channelThreeArrById[$row['channel_three_id']];
            $data[$key]['company'] = $companyArrById[$row['agent_company_id']];
            $data[$key]['person'] = $personArrById[$row['agent_person_id']];
            $data[$key]['admin'] = $adminArrById[$row['admin_uid']];
        }


        $shortLinkIds = array_filter(array_column($data, 'short_link_id')) ?: [];
        $list = ShortLink::all($shortLinkIds, ['id', 'short_link', 'long_link']);

        $list = array_column($list, null, 'id');
        foreach ($data as &$datum) {
            $datum['short_link_url'] = $datum['short_link_id'] ? self::SHORT_PREFIX . $list[$datum['short_link_id']]['short_link'] : '';
            $datum['long_link_url'] = $datum['short_link_id'] ? $list[$datum['short_link_id']]['long_link'] : '';
        }
        $version = UploadApkLog::getLastVersion();
        $gridModel = new pGridDataModel($data, $total, [
            'perPage' => $params['per_page'],
        ]);
        Admin::script($this->putAll());
        Admin::script($this->createIosDefaultUrl());
        Admin::script($this->putOne());
        $listGrid = Admin::grid($gridModel, function (Grid $grid) use ($gridModel, $version) {
            $grid->paginate($gridModel->getPerPage());

            $grid->batchActions(function (Grid\Tools\BatchActions $batch) {
                $batch->disableDelete();

                $batch->add('恢复投放', new ReleasePost(1));
                $batch->add('停止投放', new ReleasePost(0));

                $batch->add(new BatchUpdateAdmin());
            });

            $grid->filter(function (Grid\Filter $filter) {
                $filter->disableIdFilter();

                $channelsOneOptions = [];
                $channelsTwoOptions = [];
                $channels = (array)Channel::select('*', [
                    'level[<=]' => 2,
                ]);
                foreach ($channels as $channel) {
                    if ($channel['level'] == 1) {
                        $channelsOneOptions[$channel['id']] = $channel['name'];
                    } elseif ($channel['level'] == 2) {
                        $channelsTwoOptions[$channel['id']] = $channel['name'];
                    }
                }

                $filter->column(1 / 3, function (Grid\Filter $filter) use ($channelsOneOptions) {
                    $filter->equal('code', '渠道编码');
                    $filter->equal('status', '投放状态')->select(Serving::STATUS_ARR);
                    $filter->equal('agent_company_id', '代理商')->select(AgentCompanyService::getAllForSelectOptions());
                });

                $filter->column(1 / 3, function (Grid\Filter $filter) use ($channelsOneOptions) {
                    $filter->equal('channel_one_id', '投放大类')
                        ->select($channelsOneOptions)
                        ->load('channel_two_id', '/admin/adServing/serving/options/');

                    $filter->equal('terminal', '端')->select(['1' => 'ios', '2' => 'android']);
                    $filter->equal('agent_person_id', '代理人')->select(AgentPersonService::getAllForSelectOptions());
                });
                $filter->column(1 / 3, function (Grid\Filter $filter) use ($channelsTwoOptions) {
                    $filter->equal('channel_two_id', '投放渠道')->select($channelsTwoOptions);

                    $userModelClass = config('admin.database.users_model');
                    $userModel = new $userModelClass();
                    $filter->equal('admin_uid', '负责人')->select($userModel::where('is_ldap', 1)->get()->pluck('name',
                        'id'));
                });
                $filter->expand();
            });

            $grid->disableExport();
//            $grid->disableRowSelector();

            $grid->tools(function (Tools $tools) use ($version) {
                $putAllHtml = ' <a class="fa put-data"  data-version="' . $version . '" href="javascript:void(0);"><button class="btn btn-info" aria-hidden="true">更新安卓渠道版本包</button></a>';
                $tools->append($putAllHtml);
            });
            $grid->column('code', '渠道编码');
            $grid->column('channel_one_id', '投放大类')->display(function () {
                return $this['channelOne']['name'];
            });
            $grid->column('channel_two_id', '投放渠道')->display(function () {
                return $this['channelTwo']['name'];
            });
            $grid->column('channel_three_id', '投放位置')->display(function () {
                return $this['channelThree']['name'];
            });
            $grid->column('agent_company_id', '代理商')->display(function () {
                return $this['company']['name'];
            });
            $grid->column('agent_person_id', '代理人')->display(function () {
                return $this['person']['name'];
            });
            $grid->column('status', '投放状态')->using(Serving::STATUS_ARR)->dot([
                1 => 'success',
                2 => 'info',
                3 => 'primary',
                0 => 'danger',
            ], 'warning');

            $grid->column('admin_uid', '负责人')->display(function () {
                if ($this['admin']) {
                    return $this['admin']['name'];
                }
                return '';
            });
            $grid->column('terminal', '端')->using([
                Serving::TERMINAL_IOS => "ios",
                Serving::TERMINAL_ANDROID => "android"
            ]);
            $grid->column('addtime', '创建时间')->display(function () {
                return $this->addtime ? date('Y-m-d H:i:s', $this->addtime) : 0;
            });


            $grid->column('short_link_url', '短连接')->copyable();
            $grid->column('long_link_url', '原始连接')->copyable();
//            $grid->column('edittime', '更新时间')->display(function () {
//                return $this->edittime ? date('Y-m-d H:i:s', $this->edittime) : 0;
//            });
            $grid->column('created_version', '安卓apk下载')->display(function () use ($version) {

                if ($this->terminal == Serving::TERMINAL_IOS) {
                    return '';
                }
                if ($version && version_compare($version, $this->created_version, '==')) {
                    $url = "https://d.hhz1.cn/hhz_" . $this->code . ".apk";
                    return '<a href="' . $url . '" target="_blank">安卓' . $version . '</a>';
                }
                return '暂无';
            });
//            $grid->column('short_link_id', 'IOS地址')->expand(function () {
//                return $this->extend;
//            });
            $grid->actions(function ($actions) use ($version) {
                $code = $actions->row->code;

                if ($actions->row->status) {
                    $actions->append('<a href="/admin/adServing/serving/' . $actions->getKey() . '/status/0"><i class="fa fa-eye"></i>停止投放</a>');
                } else {
                    $actions->append('<a href="/admin/adServing/serving/' . $actions->getKey() . '/status/1"><i class="fa fa-eye"></i>恢复投放</a>');
                }
                $putHtml = '';
                if ($actions->row->terminal == Serving::TERMINAL_ANDROID) {
                    if (!$version || version_compare($version, $actions->row->created_version, '<>')) {
                        $putHtml = ' <a class="fa fa-send-o put-one-data" data-code="' . $code . '" data-version="' . $version . '" href="javascript:void(0);" style="margin-right: 5px">
                                    <span class="glyphicon" aria-hidden="true">生成' . $version . '渠道包</span></a>';
                    }
                } else {
                    $putHtml = ' <a class="fa fa-send-o create_ios_url" data-code="' . $code . '"  data-short-id="' . $actions->row->short_link_id . '" href="javascript:void(0);" style="margin-right: 5px">
                                    <span class="glyphicon" aria-hidden="true">生成IOS下载连接</span></a>';
                }

                $actions->append($putHtml);

            });


        });

        return $content
            ->header('投放渠道管理')
            ->breadcrumb(['text' => '投放渠道管理'])
            ->body($listGrid);
    }

    public function updateServingStatus(int $id, int $status)
    {
        Serving::update(['status' => $status], ['id' => $id,]);
        $success = new MessageBag([
            'title' => '设置成功'
        ]);
        return redirect('/admin/adServing/serving')->with(compact('success'));
    }


    /**
     * @param Content $content
     * @param int $id
     * @return Content
     */
    public function edit(Content $content, int $id = 0): Content
    {
        $tab = new Tab();
        if ($id > 0) {
            $title = '编辑投放渠道';

            $data = Serving::get('*', [
                'id' => $id,
            ]);
            $form = new Form($data);
            $form->hidden('id');
        } else {
            $title = '创建投放渠道';
            $form = new Form();
        }

        $agentCompanyOptions = [];
        $companyRows = (array)AgentCompany::select('*', []);
        foreach ($companyRows as $company) {
            $agentCompanyOptions[$company['id']] = $company['name'];
        }

        $agentPersonOptions = [];
        $personRows = (array)AgentPerson::select('*', []);
        foreach ($personRows as $person) {
            $agentPersonOptions[$person['id']] = $person['name'];
        }
        $form->checkbox('terminal', '端')
            ->rules('required')
            ->options([Serving::TERMINAL_IOS => 'ios', Serving::TERMINAL_ANDROID => 'android']);


        $form->select('channel_one_id', '投放大类')
            ->required()
            ->options(ChannelService::getChannelSelectOptionsByLevel(1))
            ->load('channel_two_id', '/admin/adServing/serving/options/');

        $form->select('channel_two_id', '投放渠道')
            ->required()
            ->options(ChannelService::getChannelSelectOptionsByLevel(2))
            ->load('channel_three_id', '/admin/adServing/serving/options/');

        $form->select('channel_three_id', '投放位置')
            ->required()
            ->options(ChannelService::getChannelSelectOptionsByLevel(3));


        $form->select('agent_company_id', '代理商')
            ->required()
            ->options($agentCompanyOptions);

        $form->select('agent_person_id', '代理人')->options($agentPersonOptions);

        $form->text('code', '渠道编码')
            ->required()
            ->placeholder('请填写渠道编码(渠道编码是唯一的不允许重复)');


        $userModelClass = config('admin.database.users_model');
        $userModel = new $userModelClass();
        $form->select('admin_uid', '负责人')
            ->required()
            ->options($userModel::where('is_ldap', 1)->get()->pluck('name', 'id'));
        $shortId = $data['short_link_id'] ?? 0;
        $defaultUrl = ShortLink::getLongLink($shortId) ?? '';

        if ($defaultUrl) {
            $info = explode('?channel=', $defaultUrl);
            $defaultUrl = $info[0] ?? '';
        }
        $form->url('url',
            '自定义投放链接')->placeholder('请填自定义投放链接（不填写默认下载链接）')->help("IOS可填写,安卓忽略")->default($defaultUrl);
        $form->text('info', '描述')->placeholder('请输入该数据域的详细信息');

        $form->action('/admin/adServing/serving/save');

        $script = <<<EOT
$(document).on('change', ".channel_three_id", function () {
    
    $("#code").attr("value","pjax-container");
    
});
EOT;
//        Admin::script($script);

        $tab->add($title, $form);
        return $content
            ->header('投放渠道管理')
            ->breadcrumb(
                [
                    'text' => '投放渠道列表',
                    'url' => '/adServing/serving'
                ],
                ['text' => "$title"]
            )
            ->body($tab);
    }


    public function getChannelSelectData(Request $request)
    {
        $channelid = (int)$request->get('q', 0);
        return ChannelService::getChannelSubSelectOptions($channelid);
    }


    public function save(Request $request)
    {
        $params = $request->all();
        $code = $params['code'];

        if (preg_match("/[\x7f-\xff]/", $code)) {
            $error = new MessageBag([
                'title' => '渠道编码,不可包含中文！',
            ]);
            return back()->with(compact('error'))->withInput();
        }


        $rs = ServingService::addServing($params);
        if ($rs === true) {
            $success = new MessageBag([
                'title' => '保存成功'
            ]);
            return redirect('/admin/adServing/serving')->with(compact('success'));
        }

        $error = new MessageBag([
            'title' => '保存失败,' . $rs,
        ]);
        return back()->with(compact('error'))->withInput();
    }

    public function del(Request $request, $idStr)
    {
        $rs = ServingService::delServing(explode(',', $idStr));
        if ($rs === true) {
            return response()->json([
                'status' => true,
                'message' => "删除成功",
            ]);
        } else {
            return response()->json([
                'status' => false,
                'message' => "删除失败," . $rs,
            ]);
        }
    }

    /**
     * 批量更新投放状态
     *
     * @param Request $request
     */
    public function release(Request $request)
    {
        $params = $request->all();
        Log::debug('批量操作', $params);

        if (in_array($params['action'], [0, 1])) {
            Serving::update(
                [
                    'status' => $params['action'],
                ],
                [
                    'id' => $params['ids']
                ]);
        }
    }

    /**
     * 批量投放js
     *
     * @return string
     */
    private function putAll()
    {
        return <<<SCRIPT
        $('.put-data').unbind('click').click(function(){
            let url = '/admin/adServing/upload/noticeAll'
      
             var version = $(this).data('version');
             if (version == 0) {
               swal({
                    title: "版本号错误,请咨询客户端是否上传包",
                    type: "warning",
                });
              return 
             }
            swal({
                    title: "确认生成好好住"+version+"版本包吗？",
                    type: "warning",
                    showCancelButton: true,
                    confirmButtonColor: "#DD6B55",
                    confirmButtonText: "确认",
                    showLoaderOnConfirm: true,
                    cancelButtonText: "取消",
                    preConfirm: function() {
                    //ajax
                        $.ajax({
                            method: 'post',
                            url: url,
                            success: function (e) {
                                if (e.code == 1) {
                                swal({
                                    title: e.title,
                                    type: "success",
                                });
                                    setTimeout(function () {
                                        $.pjax.reload('#pjax-container');
                                    }, 1000);
                                } else {
                                    toastr.error(e.title, null, {
                                        timeOut : 3000
                                    }); 
                                }
                            }
                        });
                    //ajax-end
                    }
            });
        });
       
SCRIPT;
    }

    /**
     * 单个投放js
     *
     * @return string
     */
    private function putOne()
    {
        return <<<SCRIPT
        $('.put-one-data').unbind('click').click(function(){
            let url = '/admin/adServing/upload/noticeOne'
            var version = $(this).data('version');
            var code = $(this).data('code');
            let params = {code:code}
             if (version == 0) {
               swal({
                    title: "版本号错误,请咨询客户端是否上传包",
                    type: "warning",
                });
              return 
             }
            swal({
                    title: "确认生成好好住"+version+"版本包吗？",
                    type: "warning",
                    showCancelButton: true,
                    confirmButtonColor: "#DD6B55",
                    confirmButtonText: "确认",
                    showLoaderOnConfirm: true,
                    cancelButtonText: "取消",
                    preConfirm: function() {
                    //ajax
                        $.ajax({
                            method: 'post',
                            url: url,
                            data: params,
                            success: function (e) {
                                if (e.code == 1) {
                                swal({
                                    title: e.title,
                                    type: "success",
                                });
                                    setTimeout(function () {
                                        $.pjax.reload('#pjax-container');
                                    }, 1000);
                                } else {
                                    toastr.error(e.title, null, {
                                        timeOut : 3000
                                    }); 
                                }
                            }
                        });
                    //ajax-end
                    }
            });
        });
       
SCRIPT;
    }


    /**
     * 单个投放js
     *
     * @return string
     */
    private function createIosDefaultUrl()
    {
        return <<<SCRIPT
        $('.create_ios_url').unbind('click').click(function(){
            let url = '/admin/adServing/serving/createIosDefaultUrl'
            var short_id = $(this).data('short_link_id');
            var code = $(this).data('code');
            let params = {code:code,short_id:short_id}
            swal({
                    title: "确认生成IOS默认下载连接吗？",
                    type: "warning",
                    showCancelButton: true,
                    confirmButtonColor: "#DD6B55",
                    confirmButtonText: "确认",
                    showLoaderOnConfirm: true,
                    cancelButtonText: "取消",
                    preConfirm: function() {
                    //ajax
                        $.ajax({
                            method: 'post',
                            url: url,
                            data: params,
                            success: function (e) {
                                if (e.code == 1) {
                                swal({
                                    title: e.title,
                                    type: "success",
                                });
                                    setTimeout(function () {
                                        $.pjax.reload('#pjax-container');
                                    }, 1000);
                                } else {
                                    toastr.error(e.title, null, {
                                        timeOut : 3000
                                    }); 
                                }
                            }
                        });
                    //ajax-end
                    }
            });
        });
       
SCRIPT;
    }


    /**
     * 创建短连接 返回id
     *
     * @param $url
     * @param $code
     * @return int|mixed|string
     * @throws \Exception
     */
    public function _getShortLinkId($url, $code)
    {
        $data = [
            'long_link' => $url,
            'long_link_app' => '',
            'short_link' => '',
            'reason' => 'ios投放-' . $code,
            'department' => "市场-ios-投放-" . $code . "-" . date('Y-m-d H:i:s'),
            'address' => '',
            'admin_id' => Admin::user()->id,
            'addtime' => time(),
            'status' => 1,
        ];
        $insertId = ShortLink::insertData($data);
        if (!$insertId) {
            throw new \Exception('创建短连接失败');
        }
        ShortLink::createShortLink($insertId, $data['long_link'], '');

        return $insertId;
    }


    /**
     * 单个投放
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function createIosUrl(Request $request)
    {
        try {
            $channel = $request->post('code', '');
            $short_id = $request->post('short_id', '');

            if (!$channel) {
                throw new \Exception('非法提交！');
            }
//            if (preg_match("/[\x7f-\xff]/", $channel)) {
//                throw new \Exception('渠道编码,不可包含中文！');
//            }
            //更新短连接
            $longUrl = "https://m.haohaozhu.cn/download-app?channel=" . $channel;
            if ($short_id) {
                ShortLink::createShortLink($short_id, $longUrl, '');
            } else {
                $short_id = $this->_getShortLinkId($longUrl, $channel);
                Serving::update(['short_link_id' => $short_id],
                    ['code' => $channel, 'terminal' => Serving::TERMINAL_IOS]);

            }
            $success = [
                'title' => "已生成:🎉 IOS版本 " . $channel . " 渠道包下载地址,请稍后刷新查看",
                'code' => 1,
            ];
        } catch (\Exception $e) {
            $success = [
                'title' => '操作失败,请重试！' . $e->getMessage(),
                'code' => 0,
            ];
        }
        return response()->json($success);
    }

}
